package com.zilue.security.util.rsa;

import com.zilue.security.algorithm.digest.SimpleDigest;
import com.zilue.security.algorithm.DigestAlgorithm;
import com.zilue.security.util.base64.Base64Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by zilue on 2017/3/29.
 */
public class RSAPublicKeyStaticUtil {
    public static Logger logger = LoggerFactory.getLogger("security-client");
    //摘要算法
    private static DigestAlgorithm digestAlgorithm;

    public static String sign = "sign";

    /**
     * 加密方式签名（公钥）
     *
     * @param paramterMap
     * @return
     */
    public static Map<String, String> encryptByPublicKey(Map<String, String> paramterMap, String publicKey) {
        try {
            byte[] publicStr = RSAUtil.encryptByPublicKey(getDigest(paramterMap), publicKey);
            String sign = Base64Util.encodeByte(publicStr);
            paramterMap.put(RSAPublicKeyStaticUtil.sign, sign);
        } catch (Exception e) {
            logger.error("公钥加密签名异常：", e);
        }
        return paramterMap;
    }

    /**
     * 加密方式验证签名（公钥）
     *
     * @param paramterMap
     * @return
     */
    public static boolean decodeByPublicKey(Map<String, String> paramterMap, String publicKey) {
        try {
            //1.取出签名参数
            String signParamter = paramterMap.get(RSAPublicKeyStaticUtil.sign);

            //2.复制一个map，移除签名
            Map<String, String> map = new HashMap<String, String>();
            map.putAll(paramterMap);
            map.remove(RSAPublicKeyStaticUtil.sign);

            //3.将签名解密成原文
            byte[] bytes = Base64Util.decodeByte(signParamter);
            byte[] privateStrAfter = RSAUtil.decryptByPublicKey(bytes, publicKey);
            System.out.println(new String(privateStrAfter));
            System.out.println(getDigest(map));
            //4.比对原文和摘要原文
            if (new String(privateStrAfter).equals(getDigest(map)))
                return true;
            else
                return false;
        } catch (Exception e) {
            logger.error("公钥解密签名异常：", e);
            return false;
        }
    }

    /**
     * 验证数字签名（数字签名只允许私钥签名，公钥验签）
     *
     * @param paramterMap
     * @return
     */
    public static boolean verifyDigitalSignature(Map<String, String> paramterMap,String publicKey) {
        try {
            //1.取出签名参数
            String signParamter = paramterMap.get(RSAPublicKeyStaticUtil.sign);
            //2.复制一个map，移除签名
            Map<String, String> map = new HashMap<String, String>();
            map.putAll(paramterMap);
            map.remove(RSAPublicKeyStaticUtil.sign);
            //3.验证数字签名
            return RSAUtil.verify(getDigest(map).getBytes("UTF-8"), publicKey, signParamter);
        } catch (Exception e) {
            logger.error("公钥验证数字签名异常：", e);
            return false;
        }
    }


    /**
     * 从参数中获取摘要的算法
     *
     * @param paramterMap
     * @return
     */
    public  static String getDigest(Map<String, String> paramterMap){
        //默认为自带的MD5摘要算法
        if (digestAlgorithm == null)
            digestAlgorithm = new SimpleDigest();

        return digestAlgorithm.getMapDigest(paramterMap);
    }

    public static void setDigestAlgorithm(DigestAlgorithm digestAlgorithm) {
        RSAPublicKeyStaticUtil.digestAlgorithm = digestAlgorithm;
    }
}
